package com.seanliao.nav.controller;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.seanliao.nav.common.response.Result;
import com.seanliao.nav.common.response.ResultBuilder;
import com.seanliao.nav.entity.Article;
import com.seanliao.nav.service.IArticleService;
import com.seanliao.nav.service.IProjectAppService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 统计Controller
 */
@Slf4j
@RestController
@RequestMapping("/statistic")
@RequiredArgsConstructor
public class StatisticController {

    private final IProjectAppService projectAppService;
    private final IArticleService articleService;
    private final SessionRegistry sessionRegistry;

    /**
     * 获取统计项
     * key:
     * appCount 应用数量
     * articleCount 文章数量
     * todayArticleCount 今日新增文章数量
     * onlineCount 当前在线人数
     */
    @GetMapping("/list")
    @PreAuthorize("@pms.hasPermission('statistic:list')")
    public Result<?> list(@RequestParam List<String> statisticKeys) {
        // 结果体
        Map<String, Object> resultMap = new HashMap<>(statisticKeys.size());
        // 根据选项获取
        for (String statisticKey : statisticKeys) {
            switch (statisticKey) {
                case "appCount" -> {
                    long count = projectAppService.count();
                    resultMap.put("appCount", count);
                }
                case "articleCount" -> {
                    long articleCount = articleService.count(new LambdaQueryWrapper<Article>()
                            .eq(Article::getIsPublish, true)
                            .eq(Article::getIsLock, false)
                            .eq(Article::getIsPrivate, false)
                    );
                    resultMap.put("articleCount", articleCount);
                }
                case "todayArticleCount" -> {
                    LocalDateTime now = LocalDateTime.now();
                    long todayArticleCount = articleService.count(new LambdaQueryWrapper<Article>()
                            .eq(Article::getIsPublish, true)
                            .eq(Article::getIsLock, false)
                            .eq(Article::getIsPrivate, false)
                            .between(Article::getPublishTime, LocalDateTimeUtil.beginOfDay(now), LocalDateTimeUtil.endOfDay(now))
                    );
                    resultMap.put("todayArticleCount", todayArticleCount);
                }

                default -> {
                }
            }
        }
        return ResultBuilder.success(resultMap);
    }

    /**
     * 获取统计项-管理员
     */
    @GetMapping("/list4admin")
    @PreAuthorize("@pms.hasPermission('statistic:list4Admin')")
    public Result<?> list4Admin(@RequestParam List<String> statisticKeys) {
        // 结果体
        Map<String, Object> resultMap = new HashMap<>(statisticKeys.size());
        // 根据选项获取
        for (String statisticKey : statisticKeys) {
            switch (statisticKey) {
                case "onlineUserCount" -> {
                    int count = 0;
                    List<Object> principles = sessionRegistry.getAllPrincipals();
                    for (Object principle : principles) {
                        if (!sessionRegistry.getAllSessions(principle, false).isEmpty()) {
                            count++;
                        }
                    }
                    resultMap.put("onlineUserCount", count);
                }
                default -> {
                }
            }
        }
        return ResultBuilder.success(resultMap);
    }

}
